iT邦幫忙

2021 iThome 鐵人賽

DAY 3
2
Modern Web

JavaScript Easy Go!系列 第 3

#3 JavaScript Crash Course 2

  • 分享至 

  • xImage
  •  

今天教 Promise Async / Await

Promise

Promise 這個東西跟時間有點關係。

簡單來說就是你先當下可能沒有東西,所以先給個承諾說東西等一下到,Promise 就是那個承諾。

但是你也知道承諾是空話,不一定會實現,可能會跳票。

Promise 也會遇到這兩種狀況: resolve 跟 reject。

let p = new Promise((resolve, reject) => {
    // 如果成功: resolve();
    // 反之: reject();
})

但其實我覺得有個 Promise 的概念就好,比較重要的是下面這些:

p.then((承諾過的東西) => {
    // 處理承諾過的東西
}).catch((跳票了) => {
    // 處理跳票的狀況
}).finally(() => {
    // 不管發生什麼狀況,都會執行
})
  • then 來接著處裡資料,可以 .then((...)=>...).then((...)=>...)... 接下去像 pipeline 一樣。
  • catch 來處裡錯誤。
  • finally 則是無論錯誤是否發生都會處理,雖是 finally 但其實可像 then 連續接下去。
  • 三者皆非強制使用,不一定 Promise 後面一定要接它們

Promise 常在做網路請求時用到,因為發起請求到拿到資料中間會有延遲,總不能讓程式一直等在那裡浪費時間,所以用 Promise 來先承諾之後有資料會來,要記得處裡。

關於這些東西跟 Concurrency 有點關係,有興趣可以用 Concurrency 關鍵字查查看。

你可能會聽過 callback,它是 Promise 出現前常用來處理具時間差問題的方法,現在也還是有被使用,但我認為現在 Promise 比較好用也比較常用。

Async / Await

昨天說到的 async function:

async function () {}

它長得其實就像是一般的函式,只不過前面加了個 async
它的回傳值其實也就是一般函式的回傳值包上 Promise

async function get3() {
    return 3;
}

get3().then(num => {
    console.log(num); // 3
});

需要注意的是,當你執行 async function 時,它會與原程式並行處裡

如果你學過 Go ,就像是 goroutine 那樣,只不過它不會切來切去,如果某人一直佔用運算資源,那它會一直獨佔

你可能會想說,如果我一開始 async function 是不是就只能用 then chain 接下去了啊?
當然不是,我們有 await

// 假設 getFile 從執行到結束存在延遲
async function getFile() {
    let file;
    
    // ...花時間找檔案賦給 file...
    
    return file;
}

(async () => {
    // await 會讓 getFile 執行完再接下去,同時解析 Promise 的值
    const file = await getFile();
})()

await 是用來等待 async function 執行完成的。

Promise.all

Promise.all() 可以用來合併複數並行 Promise ,常用於等待複數並行 Promise 全部執行完成

(async () => {
    // 同時向 A, B, C 三方取得資料, tasks 為 3 Promise 組成之陣列
    const tasks = [
        getDataFromA(),
        getDataFromB(),
        getDataFromC()
    ];
    const data = await Promise.all(tasks); // 等待所有 tasks 中的 Promise 完成
    // data 會是所有 tasks 中的 Promise 的值組成的陣列
})()

Promise.race

Promise.race()Promise.all() 都是在複數 Promise 間建立關係,不過它則是只等待複數並行 Promise 其中最早的執行完成

(async () => {
    // 同時向 A, B, C 三方取得資料, tasks 為 3 Promise 組成之陣列
    const tasks = [
        getDataFromA(),
        getDataFromB(),
        getDataFromC()
    ];
    const data = await Promise.race(tasks); // 等待所有 tasks 中的最早的 Promise 完成
    // data 會是最早完成的 Promise 的值
})()

每日鐵人賽熱門 Top 10 (0916)

以 9/16 12:00 ~ 9/17 12:00 文章觀看數增加值排名

  1. +447 Day 3 雲端四大平台比較:AWS . GCP . Azure . Alibaba
    • 作者: 用圖片高效學程式
    • 系列:無限手套 AWS 版:掌控一切的 5 + 1 雲端必學主題
  2. +419 [Angular 深入淺出三十天:表單與測試] Day01 - 前言
    • 作者: Leo
    • 系列:Angular 深入淺出三十天:表單與測試
  3. +413 Proxmox VE 準備與安裝
    • 作者: Jason Cheng (節省哥)
    • 系列:突破困境:企業開源虛擬化管理平台
  4. +258 Day 1-酸酸甜甜的湘粵美人-糖醋排骨
    • 作者: headhunter_sharon
    • 系列:雪倫的30天拜託冰箱
  5. +237 [Day13] 搶 PS5 程式怎麼寫? 動態爬蟲詳細教學!
    • 作者: lulu_meat
    • 系列:奇怪的知識增加了!原來程式還可以這樣用?!
  6. +216 [Day15] 明天是女友的生日卻忘記準備禮物? 教你三秒做出愛心照片牆!
    • 作者: lulu_meat
    • 系列:奇怪的知識增加了!原來程式還可以這樣用?!
  7. +208 [Day14] 家裡WiFi被媽媽鎖了怎麼辦? 教你用Python破解WiFi密碼 !
    • 作者: lulu_meat
    • 系列:奇怪的知識增加了!原來程式還可以這樣用?!
  8. +204 D01 - 萬事起頭難
    • 作者: 鱈魚
    • 系列:你渴望連結嗎?將 Web 與硬體連上線吧!
  9. +190 [Day16] 再也不用靠線上工具! 用Python把圖片轉成ASCII文字圖!
    • 作者: lulu_meat
    • 系列:奇怪的知識增加了!原來程式還可以這樣用?!
  10. +154 Day 01 X 系列文大綱
    • 作者: 莫力全 Kyle Mo
    • 系列:今晚,我想來點 Web 前端效能優化大補帖!

有趣小程式的系列文被擠下去了


上一篇
#2 JavaScript Crash Course 1
下一篇
#4 Array & Object in JavaScript
系列文
JavaScript Easy Go!31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
limitx0
iT邦新手 5 級 ‧ 2021-09-17 22:52:19

優質

0
arguskao
iT邦新手 4 級 ‧ 2022-12-30 08:26:37

這一篇就完全不懂了!

我要留言

立即登入留言